<script setup>
// import { nextTick } from 'vue'
import { Chart } from '@antv/g2'

const props = defineProps({
  data: {
    type: Array,
    default: () => [],
  },
  ready: {
    type: Boolean,
    default: false,
  },
})

let chartInstance = null
const chartDomRef = ref(null)

const state = reactive({
  isInited: false,
  mounted: false,
  mountCheckCount: 0,
})

const isNoData = computed(() => state.isInited && !props.data.length)

// 初始化渲染图表
const createChartView = (container, { width, height }) => {
  // console.log('%c%s', 'font-size:2em;background: #00965E;color: #FFF', '初始化图表', { width, height })
  const chart = new Chart({
    container,
    autoFit: true,
    height: height || 196,
    marginLeft: -2,
    marginTop: 0,
  })

  // 找出props.data中releaseNum和alarmNum的公共最大值
  const maxNum = Math.max(...props.data.map(item => item.releaseNum), ...props.data.map(item => item.alarmNum))

  const legendScheme = {
    alarmNum: { color: '#EE6A54', text: '告警信息' },
    releaseNum: { color: '#fa9d43', text: '消除信息' },
  }

  chart
    .data(props.data)
    .scale('x', {
      range: [0, 1],
    })
    .scale('y', {
      // nice: true, // 取消自动调整 y 轴的最大值
      domain: [0, maxNum && maxNum >= 4 ? parseInt(maxNum * 1.25) : maxNum + 4],
    })
    .axis('x', {
      title: false,
      size: 28,
      labelFontSize: 11,
      labelSpacing: 4,
      labelLineWidth: 1,
      labelFormatter: (text) => {
        if(text.length > 5) {
          // 如果文本超过 5 个字符，每 3 个字符插入换行
          return text.match(/.{1,3}/g).join('\n')
        }
        else {
          // 如果文本不超过 5 个字符，在第 2 个字符后插入换行
          return `${text.slice(0, 2)}\n${text.slice(2)}`
        }
      },
    })
    .axis('y', {
      title: false,
      // labelFilter: (datum, idx) => idx % 2 === 0,
      // gridFilter: (datum, idx) => idx % 2 === 0,
    })
    .legend('color', {
      itemMarker: d => () => {
        const { document } = chart.getContext().canvas
        const rect = document.createElement('rect', {
          style: {
            x: 0,
            y: d === 'alarmNum' ? -2 : -30,
            width: d === 'alarmNum' ? 4 : 160,
            height: d === 'alarmNum' ? 4 : 60,
            anchor: '0.5 0.5',
            fill: legendScheme[d].color,
            radius: d === 'alarmNum' ? 4 : 4,
            marginLeft: 20,
          },
        })
        return rect
      },
      itemSpacing: [10, 1, 1],
      itemMarkerSize: 10,
      itemLabelText: (d) => {
        const key = d?.id || d
        return legendScheme[key].text
      },
      colPadding: 20,
      layout: {
        justifyContent: 'flex-start',
        alignItems: 'flex-end',
        flexDirection: 'column',
      },
    })
    .theme({ type: 'custom' })
    // .style({
    //   viewFill: '#4e79a7',
    //   plotFill: '#f28e2c',
    //   mainFill: '#e15759',
    //   contentFill: '#76b7b2',
    // })

  chart.interval()
    .encode('x', 'robotName')
    .encode('y', 'releaseNum')
    .tooltip({
      name: '消除信息',
      field: 'releaseNum',
      color: '#fa9d43',
      channel: 'y',
    })
    .tooltip({
      name: '告警信息',
      field: 'alarmNum',
      color: '#EE6A54',
      channel: 'y',
    })
    .encode('color', () => 'releaseNum')
    .style({
      minWidth: 6,
      maxWidth: 10,
      fill: 'linear-gradient(90deg, #fa9d430A 0%, #fa9d43 100%)',
    })
  chart.line()
    .encode('x', 'robotName')
    .encode('y', 'alarmNum')
    .tooltip({
      name: '消除信息',
      field: 'releaseNum',
      color: '#fa9d43',
      channel: 'y',
    })
    .tooltip({
      name: '告警信息',
      field: 'alarmNum',
      color: '#EE6A54',
      channel: 'y',
    })
    .encode('color', () => 'alarmNum')
    .encode('shape', 'smooth')
    .style({
      lineWidth: 1.5,
      stroke: '#EE6A54',
    })
  chart.point()
    .encode('x', 'robotName')
    .encode('y', 'alarmNum')
    .encode('color', () => 'alarmNum')
    .scale('y', { independent: true, domainMin: 0 })
    .axis('y', null)
    .tooltip(null)
    .style({
      fill: '#EE6A54',
      stroke: '#EE6A54',
      lineWidth: 1,
    })
  chart.point()
    .encode('x', 'robotName')
    .encode('y', 'releaseNum')
    .encode('color', () => 'releaseNum')
    .encode('shape', 'hyphen')
    .encode('size', 5)
    .scale('y', { independent: true, domainMin: 0 })
    .axis('y', null)
    .tooltip(null)
    .style({
      fill: '#fa9d43',
      stroke: '#fa9d43',
      lineWidth: 3,
    })

  chart.render()

  state.isInited = true

  return chart
}

// 更新图表数据
const updateChartView = (chart) => {
  // 获得 Interval Mark
  // const interval = chart.getNodesByType('interval')[0]

  // // 模拟并且更新 Interval 的数据
  // const newData = interval.data().map(d => ({
  //   ...d,
  //   sold: Math.random() * 400 + 100,
  // }))

  // interval.data(newData)

  chart.changeData(props.data)

  // 重新渲染
  chart.render()
}

watch([() => props.data, () => props.ready, () => state.mountCheckCount], ([newData, newReady]) => {
  if(state.isInited && chartInstance) {
    // 已经初始化过图表, 直接更新数据
    // console.log('%c%s', 'font-size:2em;background: #00965E;color: #FFF', '更新图表数据', newData)
    updateChartView(chartInstance)
  }
  else {
    // 查看数据接口是否已经准备好
    if(props.ready || newReady) {
      if(!state.mounted) {
        setTimeout(() => {
          state.mountCheckCount++
        }, 20)
        return
      }
      if(newData?.length && chartDomRef.value) {
        // 请求数据成功, 初始化图表
        const { width, height } = chartDomRef.value.getBoundingClientRect()
        chartInstance = createChartView(chartDomRef.value, { width, height })
        // console.log('%c%s', 'font-size:2em;background: #00965E;color: #FFF', '初始化图表', newData)
      }
      else {
        // 图标数据为空，更新初始化状态, 展示缺省空状态
        state.isInited = true
        // console.log('%c%s', 'font-size:2em;background: #DD5644;color: #FFF', '图表数据为空')
      }
    }
    else {
      // console.log('%c%s', 'font-size:2em;background: #DD5644;color: #FFF', '等待数据请求完成', newData)
    }
  }
}, { deep: true, immediate: true })

onMounted(() => {
  state.mounted = true
})
</script>

<template>
  <section class="chart-alarm-stats">
    <div ref="chartDomRef" class="panel-layout panel-layout--chart" />
    <UiEmpty v-show="isNoData.value" />
  </section>
</template>

<style lang='scss' scoped>
.chart-alarm-stats {
  height: 100%;
  padding: 16px 0;
}

.panel-layout {
  &--chart {
    display: flex;
    width: 100%;
    height: 100%;
  }
}
</style>
